
#include <BLabel>
#include <BGridLayout>
#include <BVBoxLayout>
#include <BHBoxLayout>
#include <BGroupBox>
#include <BStackLayout>
#include <BColorDialog>

#include "LineStripePanel.h"
#include "StringUtils.h"
#include "ShapeBoard.h"

ShapeBoard::ShapeBoard(BWidget* parent) : Board(parent)
{
	this->setTitle("BShape");
	this->setTitleAlign(Align_Center);

	_shape = 0;

	BGridLayout* topLayout = new BGridLayout();
	{
		_enabledCheckBox = new BCheckBox("enabled");
		_visibleCheckBox = new BCheckBox("visible");
		_collidingCheckBox = new BCheckBox("colliding");
		_lightingCheckBox = new BCheckBox("lighting");
		topLayout->addWidget(0, 0, _enabledCheckBox);
		topLayout->addWidget(0, 1, _visibleCheckBox);
		topLayout->addWidget(1, 0, _collidingCheckBox);
		topLayout->addWidget(1, 1, _lightingCheckBox);
	}

	BGridLayout* transformLayout = new BGridLayout();
	{
		_positionEdit = new BLineEdit();
		_rotateEdit = new BLineEdit();

		transformLayout->addWidget(0, 0, new BLabel("position"));
		transformLayout->addWidget(0, 1, _positionEdit);
		transformLayout->addWidget(1, 0, new BLabel("rotate"));
		transformLayout->addWidget(1, 1, _rotateEdit);
	}
		
	BGridLayout* gridLayout = new BGridLayout();
	{
		_lineWidthSpinBox = new BFloatSpinBox();

		_pointSizeSpinBox = new BFloatSpinBox();

		_polyModeComboBox = new BComboBox();
		_polyModeComboBox->addItem("none", Poly_None);
		_polyModeComboBox->addItem("fill", Poly_Fill);
		_polyModeComboBox->addItem("line", Poly_Line);
		_polyModeComboBox->addItem("point", Poly_Point);

		_depthOffsetSpinBox = new BFloatSpinBox();

		gridLayout->addWidget(0, 0, new BLabel("line-width"));
		gridLayout->addWidget(0, 1, _lineWidthSpinBox);
		gridLayout->addWidget(1, 0, new BLabel("point-size"));
		gridLayout->addWidget(1, 1, _pointSizeSpinBox);
		gridLayout->addWidget(2, 0, new BLabel("poly-mode"));
		gridLayout->addWidget(2, 1, _polyModeComboBox);
		gridLayout->addWidget(3, 0, new BLabel("depth-offset"));
		gridLayout->addWidget(3, 1, _depthOffsetSpinBox);
		gridLayout->setColumnPolicy(0, Policy_Preferred);
	}

	BVBoxLayout* stateLayout = new BVBoxLayout();
	{
		_cullbackCheckBox = new BCheckBox("cullback");
		_depthTestCheckBox = new BCheckBox("depth-test");
		_pointSmoothCheckBox = new BCheckBox("point-smooth");
		_lineSmoothCheckBox = new BCheckBox("line-smooth");
		_polySmoothCheckBox = new BCheckBox("poly-smooth");
		_transparentCheckBox = new BCheckBox("transparent");

		stateLayout->addWidget(_cullbackCheckBox);
		stateLayout->addWidget(_depthTestCheckBox);
		stateLayout->addWidget(_pointSmoothCheckBox);
		stateLayout->addWidget(_lineSmoothCheckBox);
		stateLayout->addWidget(_polySmoothCheckBox);
		stateLayout->addWidget(_transparentCheckBox);
	}

	_classNameLabel = new BLabel();
	_classNameLabel->setStyleSheet("background:200, 210, 220;");

	BStackLayout* stackLayout = new BStackLayout("stack");
	stackLayout->addWidget(new LineStripePanel);

	BVBoxLayout* vlayout = new BVBoxLayout(this);
	vlayout->addLayout(topLayout);
	vlayout->addLayout(transformLayout);
	vlayout->addLayout(gridLayout);
	vlayout->addWidget(_classNameLabel);
	vlayout->addLayout(stackLayout);

	connect(this, Signal_AssetChanged, &ShapeBoard::slotAssetChanged);

	connect(_positionEdit, Signal_EditFinished, &ShapeBoard::slotPositionEditFinished);
	connect(_rotateEdit, Signal_EditFinished, &ShapeBoard::slotRotateEditFinished);

	connect(_enabledCheckBox, Signal_Toggled, &ShapeBoard::slotEnableCheckBoxToggled);
	connect(_visibleCheckBox, Signal_Toggled, &ShapeBoard::slotVisibleCheckBoxToggled);
	connect(_collidingCheckBox, Signal_Toggled, &ShapeBoard::slotCollidingCheckBoxToggled);
	connect(_lightingCheckBox, Signal_Toggled, &ShapeBoard::slotLightingCheckBoxToggled);

	connect(_lineWidthSpinBox, Signal_ValueEdited, &ShapeBoard::slotLineWidthEdited);
	connect(_pointSizeSpinBox, Signal_ValueEdited, &ShapeBoard::slotPointSizeEdited);
	connect(_polyModeComboBox, Signal_ItemClicked, &ShapeBoard::slotPolygonModeToggled);
	connect(_depthOffsetSpinBox, Signal_EditFinished, &ShapeBoard::slotDepthOffsetEditFinished);

	connect(_cullbackCheckBox, Signal_Toggled, &ShapeBoard::slotCullbackToggled);
	connect(_depthTestCheckBox, Signal_Toggled, &ShapeBoard::slotDepthTestToggled);
	connect(_pointSmoothCheckBox, Signal_Toggled, &ShapeBoard::slotPointSmoothToggled);
	connect(_lineSmoothCheckBox, Signal_Toggled, &ShapeBoard::slotLineSmoothToggled);
	connect(_polySmoothCheckBox, Signal_Toggled, &ShapeBoard::slotPolygonSmoothToggled);
	connect(_transparentCheckBox, Signal_Toggled, &ShapeBoard::slotTransparentToggled);
}
ShapeBoard::~ShapeBoard()
{

}

void ShapeBoard::slotAssetChanged(BObject* object, const BValue& value)
{
	BShape* shape = value;
	if (_shape != shape)
	{
		if (_shape)
		{
			disconnect(_shape);
		}
		_shape = shape;
		if (_shape)
		{
			_enabledCheckBox->setChecked(_shape->enabled());
			_visibleCheckBox->setChecked(shape->visible());
			_collidingCheckBox->setChecked(shape->colliding());

			_positionEdit->setText(StringFromVector(shape->position()));
			_rotateEdit->setText(StringFromQuater(shape->rotate()));

			_lineWidthSpinBox->setValue(_shape->lineWidth());
			_pointSizeSpinBox->setValue(_shape->pointSize());
			_polyModeComboBox->setValue(_shape->polyMode());
			_depthOffsetSpinBox->setValue(_shape->depthOffset());
			_lightingCheckBox->setChecked(_shape->lighting());
			_cullbackCheckBox->setChecked(_shape->cullback());
			_depthTestCheckBox->setChecked(_shape->depthTest());
			_pointSmoothCheckBox->setChecked(_shape->pointSmooth());
			_lineSmoothCheckBox->setChecked(_shape->lineSmooth());
			_polySmoothCheckBox->setChecked(_shape->polySmooth());
			_transparentCheckBox->setChecked(_shape->transparent());

			_classNameLabel->setText(_shape->className());

			BStackLayout* stackLayout = (BStackLayout*)this->layout("stack");
			for (int i = 0; i < stackLayout->count(); i++)
			{
				BWidget* widget = stackLayout->widget(i);
				if (!widget)
					continue;
				if (widget->title() == _shape->className())
				{
					widget->setAsset(_shape);
					stackLayout->setCurrent(widget);
					break;
				}
			}
			this->adjust();
		}
	}
	this->setVisible(_shape);
}

void ShapeBoard::slotPositionEditFinished(BObject* object, const BValue& value)
{

}
void ShapeBoard::slotRotateEditFinished(BObject* object, const BValue& value)
{

}

void ShapeBoard::slotEnableCheckBoxToggled(BObject* object, const BValue& value)
{
	if (_shape)
	{
		bool checked = value;
		_shape->setEnabled(checked);
	}
}
void ShapeBoard::slotVisibleCheckBoxToggled(BObject* object, const BValue& value)
{
	if (_shape)
	{
		bool visible = _visibleCheckBox->checked();
		_shape->setVisible(visible);
	}
}
void ShapeBoard::slotCollidingCheckBoxToggled(BObject* object, const BValue& value)
{
	if (_shape)
	{
		bool colliding = _collidingCheckBox->checked();
		_shape->setColliding(colliding);
	}
}
void ShapeBoard::slotLightingCheckBoxToggled(BObject* object, const BValue& value)
{
	if (_shape)
	{
		bool checked = value;
		_shape->setLighting(checked);
	}
}

void ShapeBoard::slotLineWidthEdited(BObject* object, const BValue& value)
{
	if (_shape)
	{
		float lineWidth = value;
		_shape->setLineWidth(lineWidth);
	}
}
void ShapeBoard::slotPointSizeEdited(BObject* object, const BValue& value)
{
	if (_shape)
	{
		float pointSize = value;
		_shape->setPointSize(pointSize);
	}
}
void ShapeBoard::slotPolygonModeToggled(BObject* object, const BValue& value)
{
	if (_shape)
	{
		BComboItem* item = value;
		_shape->setPolyMode(item->value());
	}
}
void ShapeBoard::slotDepthOffsetEditFinished(BObject* object, const BValue& value)
{
	if (_shape)
	{
		float offset = value;
		_shape->setDepthOffset(offset);
	}
}

void ShapeBoard::slotCullbackToggled(BObject* object, const BValue& value)
{
	if (_shape)
	{
		bool cullback = value;
		_shape->setCullback(cullback);
	}
}
void ShapeBoard::slotDepthTestToggled(BObject* object, const BValue& value)
{
	if (_shape)
	{
		bool depthTest = value;
		_shape->setDepthTest(depthTest);
	}
}
void ShapeBoard::slotPointSmoothToggled(BObject* object, const BValue& value)
{
	if (_shape)
	{
		bool pointSmooth = value;
		_shape->setPointSmooth(pointSmooth);
	}
}
void ShapeBoard::slotLineSmoothToggled(BObject* object, const BValue& value)
{
	if (_shape)
	{
		bool lineSmooth = value;
		_shape->setLineSmooth(lineSmooth);
	}
}
void ShapeBoard::slotPolygonSmoothToggled(BObject* object, const BValue& value)
{
	if (_shape)
	{
		bool polySmooth = value;
		_shape->setPolySmooth(polySmooth);
	}
}
void ShapeBoard::slotTransparentToggled(BObject* object, const BValue& value)
{
	if (_shape)
	{
		bool transparent = value;
		_shape->setTransparent(transparent);
	}
}
